#include <jni.h>
#include <string>
#include <android/bitmap.h>
#include<android/log.h>

extern "C" {
#include "gif_lib.h"
}

#define TAG "123123" // 这个是自定义的LOG的标识
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG ,__VA_ARGS__) // 定义LOGD类型
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG ,__VA_ARGS__) // 定义LOGI类型
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,TAG ,__VA_ARGS__) // 定义LOGW类型
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG ,__VA_ARGS__) // 定义LOGE类型
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,TAG ,__VA_ARGS__) // 定义LOGF类型

# define argb(a, r, g, b) ( ((a) & 0xff) << 24 ) | ( ((b) & 0xff) << 16 ) | ( ((g) & 0xff) << 8 ) | ( ((r) & 0xff) )

double persent=1.0;

//播放状态
struct GifBean {
    int cur_frame;
    int total_frame;
    int *delays;
};

void drawFrame(GifFileType *, AndroidBitmapInfo info, int *pixles);

extern "C"
JNIEXPORT jlong JNICALL
Java_com_gifcpp_play_GifHandler_loadGif(JNIEnv *env, jclass clazz, jstring path_) {

    const char *path = env->GetStringUTFChars(path_, 0);


    int error = 0;
    GifFileType *fileType = DGifOpenFileName(path, &error);

    //初始化缓冲区
    DGifSlurp(fileType);

    GifBean *gifBean = static_cast<GifBean *>(malloc(sizeof(GifBean)));
    memset(gifBean, 0, sizeof(GifBean));

    fileType->UserData = gifBean;
    gifBean->cur_frame = 0;
    gifBean->total_frame = fileType->ImageCount;


    env->ReleaseStringUTFChars(path_, path);
    return (jlong) (fileType);

}




extern "C"
JNIEXPORT jint JNICALL
Java_com_gifcpp_play_GifHandler_getWidth(JNIEnv *env, jclass clazz, jlong gif_handler) {
    GifFileType *gifFileType = reinterpret_cast<GifFileType *>(gif_handler);
    return gifFileType->SWidth;
}







extern "C"
JNIEXPORT jint JNICALL
Java_com_gifcpp_play_GifHandler_getHeight(JNIEnv *env, jclass clazz, jlong gif_handler) {
    GifFileType *gifFileType = reinterpret_cast<GifFileType *>(gif_handler);
    return gifFileType->SHeight;
}


extern "C"
JNIEXPORT jint JNICALL
Java_com_gifcpp_play_GifHandler_updateFrame(JNIEnv *env, jclass clazz, jlong gif_handler,
                                            jobject bitmap) {

    GifFileType *gifFileType = reinterpret_cast<GifFileType *>(gif_handler);
//    int width = gifFileType->SWidth;
//    int height = gifFileType->SHeight;

    AndroidBitmapInfo info;
    AndroidBitmap_getInfo(env, bitmap, &info);
//    int width=info->width;
//    int height=info->height;

    GifBean *gifBean = static_cast<GifBean *>(gifFileType->UserData);



    int *pixels;
    AndroidBitmap_lockPixels(env, bitmap, reinterpret_cast<void **>(&pixels));

    drawFrame(gifFileType, info, pixels);

    AndroidBitmap_unlockPixels(env, bitmap);


    GraphicsControlBlock gcb;
    DGifSavedExtensionToGCB(gifFileType,gifBean->cur_frame,&gcb);
    //10毫秒为一个单位，所以要*10
    int delayTime= gcb.DelayTime*10;

    gifBean->cur_frame++;
    if (gifBean->cur_frame >= gifBean->total_frame) {
        gifBean->cur_frame = 0;
//        return -1;
    }

    LOGI("delayTime :%d",delayTime);

    return delayTime;
}


void drawFrame(GifFileType *gifFileType, AndroidBitmapInfo info, int *pixels) {
    GifBean *gifBean = static_cast<GifBean *>(gifFileType->UserData);

    SavedImage savedImage = gifFileType->SavedImages[gifBean->cur_frame];

    //每一帧分为两部分，描述和像素
    //描述
    GifImageDesc frameInfo = savedImage.ImageDesc;
    //像素
    GifByteType *rasterBits = savedImage.RasterBits;

    ColorMapObject *colorMapObject = frameInfo.ColorMap;
    if(colorMapObject==nullptr){
        LOGI("---------------------------pos:%d isNull",gifBean->cur_frame);
        colorMapObject=gifFileType->SColorMap;
    }else{
        LOGI("===========================pos:%d NotNull",gifBean->cur_frame);
    }

    int *px = pixels;
    int *line=NULL;
    int pointPixels;

//    frameInfo.Top=0;
    for (int y = frameInfo.Top; y < (frameInfo.Top + frameInfo.Height); y++) {

        //每次遍历行，首地址传给line
        line = px;

//        frameInfo.Left=0;
        for (int x = frameInfo.Left; x < (frameInfo.Left + frameInfo.Width); x++) {
            //定位到像素
            pointPixels = (y - frameInfo.Top) * frameInfo.Width + (x - frameInfo.Left);

            GifByteType gbt = rasterBits[pointPixels];

            GifColorType colorType = colorMapObject->Colors[gbt];
            int r=colorType.Red*persent;
            int g=colorType.Green*persent;
            int b=colorType.Blue*persent;
            line[x] = argb(255, r, g, b);

//            line[x] = argb(255, 255 ,0, 0);

        }

//        LOGI("start y:%d",y);
        //遍历条件，转到下一行
        //stride表示一个点位，4个点代表一个像素
        //比如1920*1080  1920*4个点位
        px = px + info.stride/4;
//        px = (int *) ((char *) px + info.stride);

//        LOGI("end y:%d",y);
    }
}



jclass mClass;
extern "C"
JNIEXPORT void JNICALL
Java_com_gifcpp_play_GifHandler_create(JNIEnv *env, jclass clazz) {
    jclass tempClass=env->FindClass("java/lang/String");
    mClass= static_cast<jclass>(env->NewGlobalRef(tempClass));
}

extern "C"
JNIEXPORT void JNICALL
Java_com_gifcpp_play_GifHandler_destory(JNIEnv *env, jclass clazz) {
    env->DeleteGlobalRef(mClass);
    mClass=NULL;
}



extern "C"
JNIEXPORT void JNICALL
Java_com_gifcpp_play_GifHandler_hight(JNIEnv *env, jobject clazz) {
    persent=persent+0.1;
    if(persent>1.0){
        persent=1.0;
    }
}
extern "C"
JNIEXPORT void JNICALL
Java_com_gifcpp_play_GifHandler_low(JNIEnv *env, jobject clazz) {
    persent=persent-0.1;
    if(persent<0){
        persent=0;
    }
}


extern "C"
JNIEXPORT void JNICALL
Java_com_gifcpp_play_GifHandler_debug(JNIEnv *env, jobject thiz) {
    //反射修改mTextString值
    jclass handlerClass=env->GetObjectClass(thiz);
    jfieldID idText=env->GetFieldID(handlerClass,"mTextString", "Ljava/lang/String;");
    jstring changedStr=env->NewStringUTF("wahaha");
    env->SetObjectField(thiz,idText,changedStr);

    //反射调用方法
    jclass activityClass=env->GetObjectClass(thiz);
    jmethodID methodId=env->GetMethodID(activityClass,"callback", "(I)V");
    env->CallVoidMethod(thiz,methodId,2);
}